# Анонимные функции

Анонимная функция, также называемая лямбда, представляет собой блок кода, 
который передается в качестве аргумента функции более высокого порядка. 
Википедия определяет [анонимную функцию](https://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%BE%D0%BD%D0%B8%D0%BC%D0%BD%D0%B0%D1%8F_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F) 
как "определение функции, не привязанное к идентификатору".

Например, возьмем коллекцию:

```dotty
val ints = List(1, 2, 3)
```

Можно создать новый список, удвоив каждый элемент в целых числах, 
используя метод `map` класса `List` и свою пользовательскую анонимную функцию:

```dotty
val doubledInts = ints.map(_ * 2)
// doubledInts: List[Int] = List(2, 4, 6)
```

Как видно из комментария, `doubleInts` содержит список `List(2, 4, 6)`. 
В этом примере анонимной функцией является часть кода: `_ * 2`.

Это сокращенный способ сказать: "Умножить данный элемент на 2".


#### Более длинные формы

Более длинными формами предыдущего примера являются следующие функции:

```dotty
val doubledInts = ints.map((i: Int) => i * 2)
val doubledInts = ints.map((i) => i * 2)
val doubledInts = ints.map(i => i * 2)
```

Все эти строки имеют одно и то же значение: 
удваивайте каждый элемент в `ints`, чтобы создать новый список, `doubledInts`.

#### Сокращение анонимных функций

Если необходимо явно указать анонимную функцию, можно использовать эту длинную форму:

```dotty
val doubledInts = ints.map((i: Int) => i * 2)
```

Анонимная функция в этом выражении такова: `(i: Int) => i * 2`

Если незнаком данный синтаксис, то можно воспринимать символ `=>` как преобразователь, 
потому что выражение преобразует список параметров в левой части символа (переменная `Int` с именем `i`) в новый результат, 
используя алгоритм справа от символа `=>` (в данном случае выражение, которое удваивает значение `Int`).

#### Сокращение выражения

Эту длинную форму можно сократить:

```dotty
val doubledInts = ints.map((i: Int) => i * 2)
```

Поскольку компилятор Scala из данных в `ints` может сделать вывод, что `i` является `Int`, объявление `Int` можно удалить:

```dotty
val doubledInts = ints.map((i) => i * 2)
```

Поскольку аргумент всего один, скобки вокруг параметра `i` можно не указывать:

```dotty
val doubledInts = ints.map(i => i * 2)
```

Поскольку Scala позволяет использовать символ `_` вместо имени переменной, 
если в функции только один параметр, код можно упростить еще больше:

```dotty
val doubledInts = ints.map(_ * 2)
```

#### Ещё короче

В других примерах можно еще больше упростить анонимные функции. 
Например, начиная с самой явной формы, можно распечатать каждый элемент в целых числах, 
используя эту анонимную функцию с методом `foreach` класса `List`:

```dotty
ints.foreach((i: Int) => println(i))
```

Как и раньше, объявление `Int` не требуется, а поскольку аргумент всего один, скобки вокруг `i` не нужны:

```dotty
ints.foreach(i => println(i))
```

Поскольку `i` используется в теле функции только один раз, выражение можно еще больше упростить с помощью символа `_`:

```dotty
ints.foreach(println(_))
```

Наконец, если анонимная функция состоит из одного вызова метода с одним аргументом, 
нет необходимости явно называть и указывать аргумент, можно написать только имя метода (здесь, `println`):

```dotty
ints.foreach(println)
```


---

**Ссылки:**

- [Scala3 book](https://docs.scala-lang.org/scala3/book/taste-functions.html)
- [Scala3 book, Anonymous Functions](https://docs.scala-lang.org/scala3/book/fun-anonymous-functions.html)
